import { BrowserWindow, ipcMain } from 'electron';
import { WebSocketClient } from './ws_client';
import ProtoMessageHandler from '../proto/ProtoMessageHandler';
import log from 'electron-log/main';

const ws_notification = new WebSocketClient(
  'ws://localhost:8000/ws/notifications',
  false,
  false,
);

export const setupNotificationIPC = (win: BrowserWindow | null) => {
  // 连接到 WebSocket 服务器
  ws_notification.connect();

  // 添加 isConnected 方法到 WebSocketClient 类
  const isConnected = () => {
    try {
      return ws_notification && ws_notification.isConnected();
    } catch (err) {
      log.error('检查连接状态时出错:', err);
      return false;
    }
  };

  // 处理发送消息到 WebSocket
  ipcMain.handle('ipc-notification', async (event, type, message) => {
    if (!isConnected()) {
      return 'WebSocket 连接未打开';
    }

    // 验证类型参数
    if (typeof type !== 'number' || type < 1) {
      return '无效的通知类型';
    }

    // 验证消息格式（必须是字符串或 Buffer）
    if (
      !message ||
      (typeof message !== 'string' && !Buffer.isBuffer(message))
    ) {
      return '无效的消息格式';
    }

    try {
      ws_notification.sendNotification(type, message);
      return `消息已发送: ${message}`;
    } catch (err) {
      log.error('发送消息到 WebSocket 时出错:', err);
      return '发送消息失败';
    }
  });

  // 安全地发送消息到渲染进程
  const sendToRenderer = (channel: string, ...args: any[]) => {
    if (win && !win.isDestroyed()) {
      try {
        win.webContents.send(channel, ...args);
      } catch (error) {
        log.error(`发送消息到渲染进程(${channel})时出错:`, error);
      }
    }
  };

  ws_notification.setOnBinaryMessageCallback((binaryData: Buffer) => {
    if (binaryData instanceof Buffer) {
      try {
        const notification = ProtoMessageHandler.decodeNotification(binaryData);
        const type = notification.type;
        const messageBuffer = notification.message;
        const timestamp = notification.timestamp;

        let messageJson;
        try {
          messageJson = JSON.parse(new TextDecoder().decode(messageBuffer));
        } catch (jsonError) {
          log.error('解析通知JSON时出错:', jsonError);
          return;
        }

        switch (type) {
          case 1:
            // 错误通知
            sendToRenderer(
              'ipc-notification-receive-error',
              messageJson.serial_id,
              messageJson.message,
            );
            break;
          case 2:
            // 搜索通知
            sendToRenderer(
              'ipc-notification-receive-search',
              messageJson.baud,
              messageJson.servo_id,
              messageJson.error_code,
            );
            break;
          case 3:
            // EEPROM数据通知
            log.info('eeprom_data ', messageJson.eeprom_data);
            sendToRenderer(
              'ipc-notification-receive-eeprom',
              messageJson.serial_id,
              messageJson.eeprom_data,
            );
            break;
          case 4:
            // RAM数据通知
            log.info('ram_data ', messageJson.ram_data);
            sendToRenderer(
              'ipc-notification-receive-ram',
              messageJson.serial_id,
              messageJson.ram_data,
            );
            break;
          case 5:
            // 内部错误通知
            sendToRenderer(
              'ipc-notification-receive-inside-error',
              messageJson.serial_id,
              messageJson.error_code,
            );
            break;
          default:
            log.info('未知通知 type:', type);
        }
      } catch (error) {
        log.error('解码通知时出错:', error);
      }
    }
  });

  // 监听 WebSocket 错误
  ws_notification.setOnErrorCallback((error: Error) => {
    log.error('WebSocket 错误:', error);
  });

  // 返回清理函数，以便外部调用
  return () => {
    try {
      ws_notification.disconnect(true);
      log.info('通知 WebSocket 连接已关闭');
    } catch (err) {
      log.error('关闭通知 WebSocket 连接时出错:', err);
    }
  };
};
